#include "sal.h"
#include "usw/include/drv_enum.h"

#include "ctc_error.h"

#include "sys_usw_common.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dmps.h"
#include "../sys_usw_interrupt_priv.h"

/*Generate the sub low table list*/

#define DEF_D(RegName, bit) \
    }; \
  uint32 RegName##_sub_low_list_tm[] = {

#define DEF_F(RegName, bit) \
    RegName##_t,

#define DEF_DD(RegName, bit) \
    }; \
    uint32 RegName##_sub_low_list_tm[] = {

#define DEF_FF_NULL(RegName, bit) \
    0,

#define DEF_FF(RegName, bit) \
    RegName##_t,


uint32 sub_low_1st_tm[] = {0,
#include "sys_tsingma_interrupt.h"
};

#undef DEF_D
#undef DEF_F
#undef DEF_DD
#undef DEF_FF_NULL
#undef DEF_FF

enum sys_tm_interrupt_type_e
{
    SYS_TM_INTR_CHIP_FATAL = 0,
    SYS_TM_INTR_CHIP_NORMAL = 1,
    SYS_TM_INTR_FUNC_PTP_TS_CAPTURE_FIFO = 2,
    SYS_TM_INTR_FUNC_PTP_TOD_PULSE_IN = 3,
    SYS_TM_INTR_FUNC_PTP_TOD_CODE_IN_RDY = 4,
    SYS_TM_INTR_FUNC_PTP_SYNC_PULSE_IN = 5,
    SYS_TM_INTR_FUNC_PTP_SYNC_CODE_IN_RDY = 6,
    SYS_TM_INTR_FUNC_PTP_SYNC_CODE_IN_ACC = 7,
    SYS_TM_INTR_FUNC_STATS_STATUS_ADDR = 8,
    SYS_TM_INTR_FUNC_MET_LINK_SCAN_DONE = 9,
    SYS_TM_INTR_FUNC_STMCTL_STATE = 10,  /*tsingma*/
    SYS_TM_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW = 11, /*tsingma*/
	SYS_TM_INTR_FUNC_CHAN_LINKDOWN_SCAN = 12,
    SYS_TM_INTR_FUNC_IPFIX_USEAGE_OVERFLOW = 13,
    SYS_TM_INTR_FUNC_FIB_ACC_LEARN_OUT_FIFO = 14,
    SYS_TM_INTR_FUNC_OAM_DEFECT_CACHE = 15,
    SYS_TM_INTR_FUNC_BSR_C2C_PKT_CONGESTION = 16,
    SYS_TM_INTR_FUNC_BSR_TOTAL_CONGESTION = 17,
    SYS_TM_INTR_FUNC_BSR_OAM_CONGESTION = 18,
    SYS_TM_INTR_FUNC_BSR_DMA_CONGESTION = 19,
    SYS_TM_INTR_FUNC_BSR_CRITICAL_PKT_CONGESTION = 20,
    SYS_TM_INTR_FUNC_OAM_AUTO_GEN = 21,
    SYS_TM_INTR_PCS_LINK_31_0 = 22,
    SYS_TM_INTR_PCS_LINK_47_32 = 23,
    SYS_TM_INTR_FUNC_MDIO_XG_CHANGE_0 = 24,
    SYS_TM_INTR_FUNC_MDIO_XG_CHANGE_1 = 25,
    SYS_TM_INTR_PCIE_BURST_DONE = 26,
    SYS_TM_INTR_DMA = 27,
    SYS_TM_INTR_GPIO = 28, /*Tsingma*/
    SYS_TM_INTR_SOC_SYS = 29,/*Tsingma*/
    SYS_TM_INTR_MAX = 30
};
typedef enum sys_tm_interrupt_type_e sys_tm_interrupt_type_t;

/*Generate the sub low table list*/
#define DEF_D(RegName, bit)
#define DEF_F(RegName, bit)

#define DEF_DD(RegName, bit) \
    }; \
  sys_intr_tbl_array_t RegName##_sub_list_tm[] = {

#define DEF_FF_NULL(RegName, bit) \
    {NULL, 0},

#define DEF_FF(RegName, bit) \
    {RegName##_sub_low_list_tm, sizeof(RegName##_sub_low_list_tm)/sizeof(RegName##_sub_low_list_tm[0])},

sys_intr_tbl_array_t sub_1st_tm[] = {{0, 0},
#include "sys_tsingma_interrupt.h"
};

#define SUB_TABLE_LIST(RegName)  RegName##_sub_list_tm

extern int32 _sys_usw_interrupt_get_status_common(uint8 lchip, uint32 tbl_id, uint32* p_bmp);
extern int32 sys_usw_qos_fcdl_state_isr(uint8 lchip, uint16 mac_id);
extern int32 _sys_usw_intr_log_normal_intr(uint8 lchip, sys_intr_abnormal_log_t log_intr);
extern int32 _sys_usw_interrupt_release_fatal(uint8 lchip, sys_intr_type_t* p_type, uint32 enable);
extern int32 _sys_usw_interrupt_release_normal(uint8 lchip, sys_intr_type_t* p_type, uint32 enable);

int32 sys_tsingma_interrupt_db_init(uint8 lchip)
{
    sys_intr_func_intr_info_t* p_func_intr_tm = NULL;
    uint8 intr_idx = 0;

    p_usw_intr_master[lchip]->p_intr_low_fatal = SUB_TABLE_LIST(SupIntrFatal);
    p_usw_intr_master[lchip]->p_intr_low_normal = SUB_TABLE_LIST(SupIntrNormal);
    p_usw_intr_master[lchip]->p_intr_sub_abnormal = SUB_TABLE_LIST(SupIntrGenCtl);

    p_usw_intr_master[lchip]->fatal_sub_cnt = sizeof(SUB_TABLE_LIST(SupIntrFatal)) / sizeof(sys_intr_tbl_array_t);
    p_usw_intr_master[lchip]->normal_sub_cnt =  sizeof(SUB_TABLE_LIST(SupIntrNormal)) / sizeof(sys_intr_tbl_array_t);
    p_usw_intr_master[lchip]->intr_word_num = 1;

    p_usw_intr_master[lchip]->p_intr_func = mem_malloc(MEM_SYSTEM_MODULE, sizeof(sys_intr_func_intr_info_t)*SYS_TM_INTR_MAX);
    if (!p_usw_intr_master[lchip]->p_intr_func)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_usw_intr_master[lchip]->p_intr_func, 0, sizeof(sys_intr_func_intr_info_t)*SYS_TM_INTR_MAX);

    for (intr_idx = SYS_TM_INTR_FUNC_PTP_TS_CAPTURE_FIFO; intr_idx < SYS_TM_INTR_MAX; intr_idx++)
    {
        p_func_intr_tm = &p_usw_intr_master[lchip]->p_intr_func[intr_idx];
        p_func_intr_tm->tbl_size = 1;
        switch (intr_idx)
        {
            case SYS_TM_INTR_FUNC_PTP_TS_CAPTURE_FIFO:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 0;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_TS_CAPTURE_FIFO;
                break;
            case SYS_TM_INTR_FUNC_PTP_TOD_PULSE_IN:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 1;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_TOD_PULSE_IN;
                break;
            case SYS_TM_INTR_FUNC_PTP_TOD_CODE_IN_RDY:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 2;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_TOD_CODE_IN_RDY;
                break;
            case SYS_TM_INTR_FUNC_PTP_SYNC_PULSE_IN:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 3;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_SYNC_PULSE_IN;
                break;
            case SYS_TM_INTR_FUNC_PTP_SYNC_CODE_IN_RDY:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 4;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_SYNC_CODE_IN_RDY;
                break;
            case SYS_TM_INTR_FUNC_PTP_SYNC_CODE_IN_ACC:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 5;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_PTP_TOD_PULSE_IN;
                break;
            case SYS_TM_INTR_FUNC_STATS_STATUS_ADDR:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 6;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_STATS_STATUS_ADDR;
                break;
            case SYS_TM_INTR_FUNC_MET_LINK_SCAN_DONE:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 7;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_MET_LINK_SCAN_DONE;
                break;
            case SYS_TM_INTR_FUNC_STMCTL_STATE:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 8;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_STMCTL_STATE;
                break;
            case SYS_TM_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 9;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW;
                break;
            case SYS_TM_INTR_FUNC_CHAN_LINKDOWN_SCAN:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 10;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_CHAN_LINKDOWN_SCAN;
                break;
            case SYS_TM_INTR_FUNC_IPFIX_USEAGE_OVERFLOW:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 11;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW;
                break;
            case SYS_TM_INTR_FUNC_FIB_ACC_LEARN_OUT_FIFO:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 12;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_FIB_ACC_LEARN_OUT_FIFO;
                break;
            case SYS_TM_INTR_FUNC_OAM_DEFECT_CACHE:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 13;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_OAM_DEFECT_CACHE;
                break;
            case SYS_TM_INTR_FUNC_BSR_C2C_PKT_CONGESTION:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 14;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_BSR_C2C_PKT_CONGESTION;
                break;
            case SYS_TM_INTR_FUNC_BSR_TOTAL_CONGESTION:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 15;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_BSR_TOTAL_CONGESTION;
                break;
            case SYS_TM_INTR_FUNC_BSR_OAM_CONGESTION:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 16;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_BSR_OAM_CONGESTION;
                break;
            case SYS_TM_INTR_FUNC_BSR_DMA_CONGESTION:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 17;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_BSR_DMA_CONGESTION;
                break;
            case SYS_TM_INTR_FUNC_BSR_CRITICAL_PKT_CONGESTION:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 18;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_BSR_CRITICAL_PKT_CONGESTION;
                break;
            case SYS_TM_INTR_FUNC_OAM_AUTO_GEN:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 19;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_OAM_AUTO_GEN;
                break;
            case SYS_TM_INTR_PCS_LINK_31_0:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->sub_tbl_id = RlmHsCtlInterruptFunc_t;
                p_func_intr_tm->bit_offset = 20;
                p_func_intr_tm->common_type = SYS_INTR_PCS_LINK_31_0;
                p_func_intr_tm->tbl_size = 1;
                break;
            case SYS_TM_INTR_PCS_LINK_47_32:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->sub_tbl_id = RlmCsCtlInterruptFunc_t;
                p_func_intr_tm->bit_offset = 21;
                p_func_intr_tm->common_type = SYS_INTR_PCS_LINK_47_32;                
                p_func_intr_tm->tbl_size = 1;
                break;
            case SYS_TM_INTR_FUNC_MDIO_XG_CHANGE_0:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 22;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_MDIO_XG_CHANGE_0;
                break;
            case SYS_TM_INTR_FUNC_MDIO_XG_CHANGE_1:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 23;
                p_func_intr_tm->common_type = SYS_INTR_FUNC_MDIO_XG_CHANGE_1;
                break;
            case SYS_TM_INTR_PCIE_BURST_DONE:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->sub_tbl_id = PcieIntfInterruptFunc_t;
                p_func_intr_tm->bit_offset = 24;
                p_func_intr_tm->common_type = SYS_INTR_PCIE_BURST_DONE;                
                p_func_intr_tm->tbl_size = 1;
                break;
            case SYS_TM_INTR_DMA:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->sub_tbl_id = DmaCtlIntrFunc_t;
                p_func_intr_tm->bit_offset = 25;
                p_func_intr_tm->common_type = SYS_INTR_DMA;                
                p_func_intr_tm->tbl_size = 1;
                break;
            case SYS_TM_INTR_GPIO:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 26;
                p_func_intr_tm->common_type = SYS_INTR_GPIO;
                break;
            case SYS_TM_INTR_SOC_SYS:
                p_func_intr_tm->tbl_id = SupIntrFunc_t;
                p_func_intr_tm->bit_offset = 27;
                p_func_intr_tm->common_type = SYS_INTR_SOC_SYS;
                break;
        }
    }

    return 0;
}

/* This function is to get the corresponding position of specific intr type in intrvec table(SupCtlIntrVec) */
int32 sys_tsingma_interrupt_get_intrvec_offset(uint8 lchip, uint32 intr_type, uint32 *p_offset)
{
    CTC_PTR_VALID_CHECK(p_offset);
    switch (intr_type)
    {
        case SYS_INTR_CHIP_FATAL:
            *p_offset = 0;
            break;
        case SYS_INTR_CHIP_NORMAL:
            *p_offset = 1;
            break;
        case SYS_INTR_FUNC_PTP_TS_CAPTURE_FIFO:
            *p_offset = 2;
            break;
        case SYS_INTR_FUNC_PTP_TOD_PULSE_IN:
            *p_offset = 3;
            break;
        case SYS_INTR_FUNC_PTP_TOD_CODE_IN_RDY:
            *p_offset = 4;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_PULSE_IN:
            *p_offset = 5;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_CODE_IN_RDY:
            *p_offset = 6;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_CODE_IN_ACC:
            *p_offset = 7;
            break;
        case SYS_INTR_FUNC_STATS_STATUS_ADDR:
            *p_offset = 8;
            break;
        case SYS_INTR_FUNC_MET_LINK_SCAN_DONE:
            *p_offset = 9;
            break;
        case SYS_INTR_FUNC_STMCTL_STATE:
            *p_offset = 10;
            break;
        case SYS_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW:
            *p_offset = 11;
            break;
        case SYS_INTR_FUNC_CHAN_LINKDOWN_SCAN:
            *p_offset = 12;
            break;
        case SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW:
            *p_offset = 13;
            break;
        case SYS_INTR_FUNC_FIB_ACC_LEARN_OUT_FIFO:
            *p_offset = 14;
            break;
        case SYS_INTR_FUNC_OAM_DEFECT_CACHE:
            *p_offset = 15;
            break;
        case SYS_INTR_FUNC_BSR_C2C_PKT_CONGESTION:
            *p_offset = 16;
            break;
        case SYS_INTR_FUNC_BSR_TOTAL_CONGESTION:
            *p_offset = 17;
            break;
        case SYS_INTR_FUNC_BSR_OAM_CONGESTION:
            *p_offset = 18;
            break;
        case SYS_INTR_FUNC_BSR_DMA_CONGESTION:
            *p_offset = 19;
            break;
        case SYS_INTR_FUNC_BSR_CRITICAL_PKT_CONGESTION:
            *p_offset = 20;
            break;
        case SYS_INTR_FUNC_OAM_AUTO_GEN:
            *p_offset = 21;
            break;
        case SYS_INTR_PCS_LINK_31_0:
            *p_offset = 22;
            break;
        case SYS_INTR_PCS_LINK_47_32:
            *p_offset = 23;
            break;
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_0:
            *p_offset = 24;
            break;
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_1:
            *p_offset = 25;
            break;
        case SYS_INTR_PCIE_BURST_DONE:
            *p_offset = 26;
            break;
        case SYS_INTR_DMA:
            *p_offset = 27;
            break;
        case SYS_INTR_GPIO:
            *p_offset = 28;
            break;
        case SYS_INTR_SOC_SYS:
            *p_offset = 29;
            break;
        default:
            *p_offset = 0xFFFF;
            return CTC_E_NOT_SUPPORT;
            break;
    }

    return CTC_E_NONE;
}

int32 sys_tsingma_interrupt_get_sup_info(uint8 lchip, uint32 intr_type, uint32 *p_sup_table_id, uint16 *p_bit_offset, uint32 *p_func_table_id)
{
    CTC_PTR_VALID_CHECK(p_sup_table_id);
    CTC_PTR_VALID_CHECK(p_bit_offset);

    switch (intr_type)
    {
        case SYS_INTR_CHIP_FATAL:
            *p_sup_table_id = SupIntrFatal_t;
            *p_bit_offset = 0; /* no use */
            break;
        case SYS_INTR_CHIP_NORMAL:
            *p_sup_table_id = SupIntrNormal_t;
            *p_bit_offset = 0; /* no use */
            break;
        case SYS_INTR_FUNC_PTP_TS_CAPTURE_FIFO:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 0;
            break;
        case SYS_INTR_FUNC_PTP_TOD_PULSE_IN:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 1;
            break;
        case SYS_INTR_FUNC_PTP_TOD_CODE_IN_RDY:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 2;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_PULSE_IN:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 3;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_CODE_IN_RDY:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 4;
            break;
        case SYS_INTR_FUNC_PTP_SYNC_CODE_IN_ACC:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 5;
            break;
        case SYS_INTR_FUNC_STATS_STATUS_ADDR:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 6;
            break;
        case SYS_INTR_FUNC_MET_LINK_SCAN_DONE:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 7;
            break;
        case SYS_INTR_FUNC_STMCTL_STATE:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 8;
            break;
        case SYS_INTR_FUNC_EPE_IPFIX_USEAGE_OVERFLOW:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 9;
            break;
        case SYS_INTR_FUNC_CHAN_LINKDOWN_SCAN:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 10;
            break;
        case SYS_INTR_FUNC_IPFIX_USEAGE_OVERFLOW:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 11;
            break;
        case SYS_INTR_FUNC_FIB_ACC_LEARN_OUT_FIFO:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 12;
            break;
        case SYS_INTR_FUNC_OAM_DEFECT_CACHE:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 13;
            break;
        case SYS_INTR_FUNC_BSR_C2C_PKT_CONGESTION:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 14;
            break;
        case SYS_INTR_FUNC_BSR_TOTAL_CONGESTION:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 15;
            break;
        case SYS_INTR_FUNC_BSR_OAM_CONGESTION:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 16;
            break;
        case SYS_INTR_FUNC_BSR_DMA_CONGESTION:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 17;
            break;
        case SYS_INTR_FUNC_BSR_CRITICAL_PKT_CONGESTION:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 18;
            break;
        case SYS_INTR_FUNC_OAM_AUTO_GEN:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 19;
            break;
        case SYS_INTR_PCS_LINK_31_0:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 20;
            break;
        case SYS_INTR_PCS_LINK_47_32:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 21;
            break;
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_0:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 22;
            break;
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_1:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 23;
            break;
        case SYS_INTR_PCIE_BURST_DONE:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 24;
            break;
        case SYS_INTR_DMA:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 25;
            break;
        case SYS_INTR_GPIO:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 26;
            break;
        case SYS_INTR_SOC_SYS:
            *p_sup_table_id = SupIntrFunc_t;
            *p_bit_offset = 27;
            break;
        default:
            *p_sup_table_id = 0; /* invalid value */
            *p_bit_offset = 0xFFFF; /* invalid value */
            return CTC_E_NOT_SUPPORT;
            break;
    }

    if (p_func_table_id)
    {
        switch (intr_type)
        {
            case SYS_INTR_PCS_LINK_31_0:
                *p_func_table_id = RlmHsCtlInterruptFunc_t;
                break;
            case SYS_INTR_PCS_LINK_47_32:
                *p_func_table_id = RlmCsCtlInterruptFunc_t;
                break;
            case SYS_INTR_PCIE_BURST_DONE:
                *p_func_table_id = PcieIntfInterruptFunc_t;
                break;
            case SYS_INTR_DMA:
                *p_func_table_id = DmaCtlIntrFunc_t;
                break;
            default:
                *p_func_table_id = 0;/* other type return invalid table id, include fatal and normal */
                break;
        }
    }

    return CTC_E_NONE;
}

/*Notice: In this function, sys_intr_type_t is tsingma sys_tm_interrupt_type_t */
int32
sys_tsingma_interrupt_get_status_func(uint8 lchip, sys_intr_type_t* p_type, uint32* p_bmp)
{
    uint32 cmd = 0;
    uint32 value[CTC_INTR_STAT_SIZE] = {0};
    uint32 mask[CTC_INTR_STAT_SIZE] = {0};
    uint8 index = 0;
    uint32 tbl_id = 0;
    uint8  cnt = 0;
    uint8 tbl_size = 0;

    p_bmp[0] = 0;
    p_bmp[1] = 0;
    p_bmp[2] = 0;
    p_bmp[3] = 0;
    if (p_usw_intr_master[lchip]->p_intr_func[p_type->intr].sub_tbl_id)
    {
        tbl_id = p_usw_intr_master[lchip]->p_intr_func[p_type->intr].sub_tbl_id;
        tbl_size = p_usw_intr_master[lchip]->p_intr_func[p_type->intr].tbl_size;
    }
    else
    {
        tbl_id = p_usw_intr_master[lchip]->p_intr_func[p_type->intr].tbl_id;        
        tbl_size = p_usw_intr_master[lchip]->intr_word_num;
    }

    /*Pcs link interrupt have three levels, need process the 3nd level first*/
    if (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0 || p_type->intr == SYS_TM_INTR_PCS_LINK_47_32)
    {
        tbl_id = (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)?Hss12GUnitWrapperInterruptFunc0_t:Hss28GUnitWrapperInterruptFunc_t;
        cnt = (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)?3:1;
        p_type->low_intr = 0;
        for (index = 0; index < cnt; index++)
        {
            _sys_usw_interrupt_get_status_common(lchip, tbl_id, p_bmp);
            if (p_bmp[0] || p_bmp[1] || p_bmp[2] || p_bmp[3])
            {
                p_type->low_intr = index;
                break;
            }
            tbl_id++;
        }

        /*if 3nd level interrupt have no value, clear all 2nd interrupt*/
        if ((index == cnt) && (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0))
        {
            cmd = DRV_IOR((RlmHsCtlInterruptFunc_t), DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, INTR_INDEX_VAL_SET, cmd, value);
            value[0] &= 7;
            cmd = DRV_IOW((RlmHsCtlInterruptFunc_t), DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, value);
        }
        return CTC_E_NONE;
    }

    cmd = DRV_IOR((tbl_id), DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, INTR_INDEX_VAL_SET, cmd, value));
    cmd = DRV_IOR((tbl_id), DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, mask));

    for(index = 0; index < tbl_size; index++)
    {
        p_bmp[index] = value[index] & (~mask[index]);
    }

    return CTC_E_NONE;
}


/*Notice: In this function, sys_intr_type_t is tsingma sys_tm_interrupt_type_t */
int32
sys_tsingma_interrupt_clear_status_func(uint8 lchip, sys_intr_type_t* p_type, uint32* bmp)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint32 sup_bmp[2] = {0};
    uint32 low_level_tbl = 0;    
#if ((SDK_WORK_PLATFORM == 1) || ((0 == SDK_WORK_PLATFORM) && (1 == SDK_WORK_ENV)))  /* simulation */
    uint8  common_intr = 0;
#endif

    /*Pcs link interrupt have three levels, need process the 3nd level first*/
    if (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0 || p_type->intr == SYS_TM_INTR_PCS_LINK_47_32)
    {
        low_level_tbl = (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)?Hss12GUnitWrapperInterruptFunc0_t:Hss28GUnitWrapperInterruptFunc_t;
        tbl_id = (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)?RlmHsCtlInterruptFunc_t:RlmCsCtlInterruptFunc_t;
        low_level_tbl = low_level_tbl + p_type->low_intr;
        
        cmd = DRV_IOW(low_level_tbl, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, bmp));
        
#if ((SDK_WORK_PLATFORM == 1) || ((0 == SDK_WORK_PLATFORM) && (1 == SDK_WORK_ENV)))  /* simulation */
        common_intr = (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)?SYS_INTR_PCS_LINK_31_0:SYS_INTR_PCS_LINK_47_32;
        _sys_usw_interrupt_model_sim_value(lchip, tbl_id, common_intr, bmp, FALSE);
#endif

        sup_bmp[0] = (1 << p_type->low_intr);
        cmd = DRV_IOW((tbl_id), DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, sup_bmp);
        sup_bmp[0] = 0;
#if ((SDK_WORK_PLATFORM == 1) || ((0 == SDK_WORK_PLATFORM) && (1 == SDK_WORK_ENV)))  /* simulation */
    _sys_usw_interrupt_model_sim_value(lchip, tbl_id, p_usw_intr_master[lchip]->p_intr_func[p_type->intr].common_type, bmp, FALSE);
#endif
    }
    else if (p_usw_intr_master[lchip]->p_intr_func[p_type->intr].sub_tbl_id)
    {
        tbl_id = p_usw_intr_master[lchip]->p_intr_func[p_type->intr].sub_tbl_id;
        cmd = DRV_IOW((tbl_id), DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, bmp));
#if ((SDK_WORK_PLATFORM == 1) || ((0 == SDK_WORK_PLATFORM) && (1 == SDK_WORK_ENV)))  /* simulation */
        _sys_usw_interrupt_model_sim_value(lchip, tbl_id, p_usw_intr_master[lchip]->p_intr_func[p_type->intr].common_type, bmp, FALSE);
#endif
    }

    sup_bmp[0] = (1 << (p_type->intr-2));
    cmd = DRV_IOW(SupIntrFunc_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, sup_bmp));

#if ((SDK_WORK_PLATFORM == 1) || ((0 == SDK_WORK_PLATFORM) && (1 == SDK_WORK_ENV)))  /* simulation */
    _sys_usw_interrupt_model_sim_value(lchip, SupIntrFunc_t, p_usw_intr_master[lchip]->p_intr_func[p_type->intr].common_type, sup_bmp, FALSE);
#endif
    return CTC_E_NONE;
}

int32
_sys_tsingma_interrupt_dispatch_func_pcs_link(uint8 lchip, sys_intr_type_t* p_type, uint32* status)
{
	uint32 tbl_id = 0;
    sys_intr_t* p_intr = NULL;
    uint32 common_intr = 0;

    if (p_type->intr == SYS_TM_INTR_PCS_LINK_31_0)
    {
        tbl_id = Hss12GUnitWrapperInterruptFunc0_t;
        common_intr = SYS_INTR_PCS_LINK_31_0;
    }
    else
    {
        tbl_id = Hss28GUnitWrapperInterruptFunc_t;
        common_intr = SYS_INTR_PCS_LINK_47_32;
    }
    p_intr = &(p_usw_intr_master[lchip]->intr[common_intr]);
	tbl_id = tbl_id + p_type->low_intr;
    p_intr->isr(lchip, tbl_id, status);

    return CTC_E_NONE;
}

int32
sys_tsingma_interrpt_dispatch_func(uint8 lchip, uint32* p_status)
{
    uint8 intr_idx = 0;
    sys_intr_type_t type;
    sys_intr_t* p_intr = NULL;
    uint32 status[CTC_INTR_STAT_SIZE] = {0};
    sys_intr_func_intr_info_t* p_func_intr_tm;

    for(intr_idx = SYS_TM_INTR_FUNC_PTP_TS_CAPTURE_FIFO; intr_idx < SYS_TM_INTR_MAX; intr_idx++)
    {
        if (!CTC_BMP_ISSET(p_status, intr_idx))
        {
            continue;
        }

        p_func_intr_tm = &p_usw_intr_master[lchip]->p_intr_func[intr_idx];

        /*get intr status*/
        type.intr = intr_idx;
        type.sub_intr = INVG;
        type.low_intr = INVG;
        type.slice_id = 0;
        sys_tsingma_interrupt_get_status_func(lchip, &type, status);

        if(status[0] == 0 && status[1] == 0 && status[2] == 0 && status[3] == 0)
        {
            /*clear SupIntrFunc*/
            CTC_ERROR_RETURN(sys_tsingma_interrupt_clear_status_func(lchip, &type, status));
            return CTC_E_NONE;
        }

        p_intr = &(p_usw_intr_master[lchip]->intr[p_func_intr_tm->common_type]);
        if (p_intr->is_event)
        {
            CTC_ERROR_RETURN(sys_tsingma_interrupt_clear_status_func(lchip, &type, status));/* status keep original value */
        }

        if (p_intr->valid)
        {
            p_intr->occur_count++;
            if (p_intr->isr)
            {
                SYS_INTR_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"Dispatch interrupt intr: %d, count: %d\n", p_func_intr_tm->common_type, p_intr->occur_count);
                if (type.intr == SYS_TM_INTR_PCS_LINK_31_0 || type.intr == SYS_TM_INTR_PCS_LINK_47_32)
                {
                    _sys_tsingma_interrupt_dispatch_func_pcs_link(lchip, &type, status);
                }
                else
                {
                    p_intr->isr(lchip, p_func_intr_tm->common_type, status);
                }
            }
        }

        if (!p_intr->is_event)
        {
            CTC_ERROR_RETURN(sys_tsingma_interrupt_clear_status_func(lchip, &type, status));
        }
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_interrupt_isr_sup_normal(uint8 lchip, uint32 intr, void* p_data)
{
    uint32* p_sup_normal = (uint32*)p_data;
    sys_intr_type_t type;
    uint32 idx = 0;
    uint32 offset = 0;
    uint32 i = 0;
    uint32 j = 0;
    uint8 gchip = 0 ;
    ctc_interrupt_abnormal_status_t abnormal_status;
    ctc_intr_status_t* p_status = &(abnormal_status.status);
    int32 ret = CTC_E_NONE;
    uint32  sub_bmp[CTC_INTR_STAT_SIZE] = {0};
    uint32  low_bmp[CTC_INTR_STAT_SIZE] = {0};
    uint8   action_type = 0;
    uint8 ecc_or_parity = 0;
    tbls_id_t intr_tbl = MaxTblId_t;
    uint8 loop = 0;
    uint16 mac_id = 0;
    uint8 flag = 0;
    sal_memset(&abnormal_status, 0, sizeof(abnormal_status));
    sal_memset(&type, 0, sizeof(sys_intr_type_t));

    type.intr = SYS_INTR_CHIP_NORMAL;

    /* 2. get & clear sub interrupt status */
    for (i = 0; i < p_usw_intr_master[lchip]->normal_sub_cnt; i++)
    {
        idx = i / CTC_UINT32_BITS;
        offset = i % CTC_UINT32_BITS;

        if (0 == p_sup_normal[idx])
        {
            /* bypass 32Bit 0 */
            i = (idx + 1) * CTC_UINT32_BITS-1;
            continue;
        }

        if (!CTC_IS_BIT_SET(p_sup_normal[idx], offset))
        {
            continue;
        }
        type.sub_intr = i;
        type.low_intr = INVG;
        type.lvl4_intr = INVG;

        /* get sub interrupt status */
        _sys_usw_interrupt_get_status_normal(lchip, &type, sub_bmp);

        if (!sub_bmp[0] && !sub_bmp[1] && !sub_bmp[2])
        {
            continue;
        }

        for (j = 0; j < CTC_INTR_STAT_SIZE * CTC_UINT32_BITS; j++)
        {
            if(!CTC_BMP_ISSET(sub_bmp, j))
            {
                continue;
            }

            sal_memset(low_bmp, 0, sizeof(low_bmp));
            type.low_intr = j;
            abnormal_status.type.intr = CTC_INTR_CHIP_NORMAL;
            abnormal_status.type.sub_intr = i;
            abnormal_status.type.low_intr = j;

            /* get low interrupt status */
            ret = _sys_usw_interrupt_get_status_normal(lchip, &type, low_bmp);
            if (ret < 0)
            {
                continue;
            }
            SYS_INTR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "sup-intr:%d sub-intr:%d low-intr:%d\n",type.intr,type.sub_intr,type.low_intr);

            for(loop = 0; loop < CTC_INTR_STAT_SIZE; loop++)
            {
                if(low_bmp[loop])
                {
                    flag = 1;
                    break;
                }
            }
            if(flag && type.sub_intr == 2 && type.low_intr <= 17 &&
                (CTC_BMP_ISSET(low_bmp, 18)||CTC_BMP_ISSET(low_bmp, 19)||CTC_BMP_ISSET(low_bmp, 20)||CTC_BMP_ISSET(low_bmp, 21)))
            {
                for(loop = 0; loop < 4; loop ++)
                {
                    if(CTC_BMP_ISSET(low_bmp, (18+loop)))
                    {
                        mac_id = type.low_intr * 4 + loop;
                        sys_usw_qos_fcdl_state_isr(lchip, mac_id);
                    }
                }
                /* clear low interrupt status in one time */
                CTC_ERROR_RETURN(_sys_usw_interrupt_clear_status_normal(lchip, &type, low_bmp));
            }
            else if(flag)
            {
                uint16 k = 0;

                /* process all low interrupt*/
                for (k = 0; k < CTC_INTR_STAT_SIZE * CTC_UINT32_BITS; k++)
                {
                    if (!CTC_BMP_ISSET(low_bmp, k))
                    {
                        continue;
                    }

                    /* no end table id */
                    sys_usw_interrupt_get_info(lchip, &type, k, &intr_tbl, &action_type, &ecc_or_parity);

                    if ( ecc_or_parity)
                    {
                        /* function interrupt for process ecc or parity */
                        sys_usw_interrupt_proc_ecc_or_parity(lchip, intr_tbl, k, abnormal_status.type);
                    }
                    else if (p_usw_intr_master[lchip]->event_cb[CTC_EVENT_ABNORMAL_INTR])
                    {
                        SYS_USW_INTR_ABNORMAL_LOG_PROCESS(lchip, CTC_INTR_CHIP_NORMAL, i, j, low_bmp);
                        ret = sys_usw_get_gchip_id(lchip, &gchip);
                        if (0 == ret)
                        {
                            abnormal_status.type.intr = CTC_INTR_CHIP_NORMAL;
                            abnormal_status.type.sub_intr = i;
                            sal_memcpy(p_status->bmp, low_bmp, sizeof(uint32)*CTC_INTR_STAT_SIZE);
                            abnormal_status.type.low_intr = j;
                            abnormal_status.action = CTC_INTERRUPT_FATAL_INTR_LOG;
                            p_usw_intr_master[lchip]->event_cb[CTC_EVENT_ABNORMAL_INTR](gchip, &abnormal_status);
                        }
                    }
                }

                /* clear low interrupt status in one time */
                CTC_ERROR_RETURN(_sys_usw_interrupt_clear_status_normal(lchip, &type, low_bmp));
            }
            else
            {
                /* no low table id */
                type.low_intr = INVG;
                sys_usw_interrupt_get_info(lchip, &type, j, &intr_tbl, &action_type, &ecc_or_parity);
                if (ecc_or_parity)
                {
                    /* function interrupt for process ecc or parity */
                    sys_usw_interrupt_proc_ecc_or_parity(lchip, intr_tbl, j, abnormal_status.type);
                }
                else if (p_usw_intr_master[lchip]->event_cb[CTC_EVENT_ABNORMAL_INTR])
                {
                    SYS_USW_INTR_ABNORMAL_LOG_PROCESS(lchip, CTC_INTR_CHIP_NORMAL,i,j,low_bmp);
                    ret = sys_usw_get_gchip_id(lchip, &gchip);
                    if (0 == ret)
                    {
                        abnormal_status.type.intr = CTC_INTR_CHIP_NORMAL;
                        abnormal_status.type.sub_intr = i;
                         /*sal_memcpy(p_status->bmp,low_bmp,sizeof(uint32)*CTC_INTR_STAT_SIZE);*/
                        abnormal_status.type.low_intr = j;
                        abnormal_status.action = CTC_INTERRUPT_FATAL_INTR_LOG;
                        p_usw_intr_master[lchip]->event_cb[CTC_EVENT_ABNORMAL_INTR](gchip, &abnormal_status);
                    }
                }
            }
        }
        /*clear sub interrup status*/
        type.low_intr = INVG;
        CTC_ERROR_RETURN(_sys_usw_interrupt_clear_status_normal(lchip, &type, sub_bmp));
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_interrupt_init_reg(uint8 lchip)
{
    sys_intr_group_t* p_group = NULL;
    ds_t map_ctl;
    SupIntrGenCtl_m gen_ctl;
    uint32 cmd = 0;
    uint32 i = 0;
    uint32 j = 0;
    uint32 mask_set = 0;
    uint32 unmask_set = 0;
    uint32 value_set = 0;
    uint8 step = 0;
    sys_intr_type_t type;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    uint32 value[CTC_INTR_STAT_SIZE] = {0};
    RlmHsCtlInterruptNormal_m hs_normal;
    RlmCsCtlInterruptNormal_m cs_normal;
    PcieIntfInterruptNormal_m pcie_normal;
    NetTxInterruptNormal_m    nettx_normal;
    QuadSgmacInterruptNormal0_m quadsgmac_normal;
    Hss12GUnitWrapperInterruptFunc0_m hss_12g;
    Hss28GUnitWrapperInterruptFunc_m hss_28g;
    IpeAclInterruptNormal_m ipe_acl_normal;
    ds_t ds;
    DmaCtlInterruptNormal_m dma_normal;
    
    sal_memset(map_ctl, 0, sizeof(map_ctl));
    sal_memset(&quadsgmac_normal, 0, sizeof(QuadSgmacInterruptNormal0_m));
    sal_memset(&gen_ctl, 0, sizeof(gen_ctl));

    mask_set = 0xFF;

    for (i = 0; i < SYS_USW_MAX_INTR_GROUP; i++)
    {
        p_group = &(p_usw_intr_master[lchip]->group[i]);
        if (p_group->group < 0)
        {
            continue;
        }

        if (p_group->group >= 0)
        {
            CTC_BIT_UNSET(mask_set, p_group->irq_idx);
        }

        switch (p_group->irq_idx)
        {
            case 0:
                value_set = GetSupIntrMapCtl(V, supIntrMap0_f, &map_ctl);
                value_set |= p_group->intr_bmp[0];
                SetSupIntrMapCtl(V, supIntrMap0_f, &map_ctl, value_set);
                break;

            case 1:
                value_set = GetSupIntrMapCtl(V, supIntrMap1_f, &map_ctl);
                value_set |= p_group->intr_bmp[0];
                SetSupIntrMapCtl(V, supIntrMap1_f, &map_ctl, value_set);
                break;

            case 2:
                value_set = GetSupIntrMapCtl(V, supIntrMap2_f, &map_ctl);
                value_set |= p_group->intr_bmp[0];
                SetSupIntrMapCtl(V, supIntrMap2_f, &map_ctl, value_set);
                break;

            case 3:
                value_set = GetSupIntrMapCtl(V, supIntrMap3_f, &map_ctl);
                value_set |= p_group->intr_bmp[0];
                SetSupIntrMapCtl(V, supIntrMap3_f, &map_ctl, value_set);
                break;

            default:
                break;
        }
    }

    unmask_set = (~mask_set)&0xff;

    SetSupIntrGenCtl(V, supIntrMaskSet_f, &gen_ctl, mask_set);
    SetSupIntrGenCtl(V, supIntrMaskClr_f, &gen_ctl, unmask_set);
    cmd = DRV_IOW(SupIntrMapCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &map_ctl));
    cmd = DRV_IOW(SupIntrGenCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &gen_ctl));

    /* release fatal interrupt mask */
    for (i = 0; i < p_usw_intr_master[lchip]->fatal_sub_cnt; i++)
    {
        /* force release sub intr even if no lower interrupt*/
        j = 0;
        do
        {
            type.intr = SYS_INTR_CHIP_FATAL;
            type.sub_intr = i;
            type.low_intr = j;
            _sys_usw_interrupt_release_fatal(lchip, &type, 1);
            j++;
        }
        while (j < p_usw_intr_master[lchip]->p_intr_low_fatal[i].array_size);
    }

    /* release normal interrupt mask */
    for (i = 0; i < p_usw_intr_master[lchip]->normal_sub_cnt; i++)
    {
        /* force release sub intr even if no lower interrupt*/
        j = 0;
        do
        {
            type.intr = SYS_INTR_CHIP_NORMAL;
            type.sub_intr = i;
            type.low_intr = j;
            _sys_usw_interrupt_release_normal(lchip, &type, 1);
            j++;
        }
        while (j < p_usw_intr_master[lchip]->p_intr_low_normal[i].array_size);
    }

    sal_memset(&hs_normal, 0, sizeof(hs_normal));
    sal_memset(&cs_normal, 0, sizeof(cs_normal));
    sal_memset(&hss_12g, 0, sizeof(hss_12g));
    sal_memset(&hss_28g, 0, sizeof(hss_28g));
    for (i = 0; i< 256; i++)
    {
        uint8 serdes_idx;
        sys_dmps_serdes_info_t  serdes_info;

        sal_memset(&serdes_info, 0, sizeof(sys_dmps_serdes_info_t));
        dmps_port_info.gport = i;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SERDES, (void *)&serdes_info));

        if(serdes_info.serdes_mode == 0xFF)
        {
            continue;
        }

        for(serdes_idx=0; serdes_idx < serdes_info.serdes_num; serdes_idx++)
        {
            uint8 tbl_offset = 0;
            uint8 field_offset = 0;

            if(serdes_info.serdes_id[serdes_idx] < 24)
            {
                tbl_offset = (serdes_info.serdes_id[serdes_idx])/8;
                field_offset = (serdes_info.serdes_id[serdes_idx])%8;
                CTC_BMP_SET((uint32*)&hss_12g, 64+6*field_offset);
                CTC_BMP_SET((uint32*)&hss_12g, 65+6*field_offset);
                CTC_BMP_SET((uint32*)&hss_12g, 66+6*field_offset);
            }
            else
            {
                tbl_offset = (serdes_info.serdes_id[serdes_idx]-24)/8;
                field_offset = (serdes_info.serdes_id[serdes_idx]-24)%8;
                CTC_BMP_SET((uint32*)&hss_28g, 16+3*field_offset);
                CTC_BMP_SET((uint32*)&hss_28g, 17+3*field_offset);
                CTC_BMP_SET((uint32*)&hss_28g, 18+3*field_offset);
            }
            cmd = DRV_IOW(Hss12GUnitWrapperInterruptFunc0_t+tbl_offset, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &hss_12g);
            cmd = DRV_IOW(Hss28GUnitWrapperInterruptFunc_t+tbl_offset, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &hss_28g);
        }
    }

    cmd = DRV_IOW(RlmCsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &cs_normal);
    cmd = DRV_IOW(RlmHsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &hs_normal);

    /* release function interrupt mask*/
    cmd = DRV_IOR(DmaCtlIntrFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &value_set);
    cmd = DRV_IOW(DmaCtlIntrFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &value_set);
    
    sal_memset(&ds, 0, sizeof(ds_t));
    /*statsRamOverflow*/
    ds[1] = 0x4000000;
    ds[0] = 0x0;
    cmd = DRV_IOW(GlobalStatsInterruptFatal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &ds);

    cmd = DRV_IOR(PcieIntfInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &value_set);
    cmd = DRV_IOW(PcieIntfInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &value_set);

    cmd = DRV_IOR(RlmCsCtlInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, value);
    cmd = DRV_IOW(RlmCsCtlInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, value);

    cmd = DRV_IOR(RlmHsCtlInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, value);
    cmd = DRV_IOW(RlmHsCtlInterruptFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, value);

    value_set = 1;
    cmd = DRV_IOW(BufRetrvInterruptNormal_t, BufRetrvInterruptNormal_dsBufRetrvExcpEccError_f);
    DRV_FIELD_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &value_set);

    sal_memset(&nettx_normal, 0, sizeof(NetTxInterruptNormal_m));
    SetNetTxInterruptNormal(V, rxNoEopErrorIntr0_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoEopErrorIntr1_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoEopErrorIntr2_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoEopErrorIntr3_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoSopErrorIntr0_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoSopErrorIntr1_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoSopErrorIntr2_f, &nettx_normal, 1);
    SetNetTxInterruptNormal(V, rxNoSopErrorIntr3_f, &nettx_normal, 1);
    cmd = DRV_IOW(NetTxInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &nettx_normal);

    /*mask dma0AxiRdSizeError for RTL bug 110000*/
    sal_memset(&dma_normal, 0, sizeof(dma_normal));
    SetDmaCtlInterruptNormal(V, dma0AxiRdSizeError_f, &dma_normal, 1);
    SetDmaCtlInterruptNormal(V, dma1AxiRdSizeError_f, &dma_normal, 1);
    SetDmaCtlInterruptNormal(V, dma2AxiRdSizeError_f, &dma_normal, 1);
    cmd = DRV_IOW(DmaCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &dma_normal);

    cmd = DRV_IOR(PcieIntfInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &pcie_normal);
    SetPcieIntfInterruptNormal(V, hssRxAEyeQualityIntr_f, &pcie_normal, 1);
    SetPcieIntfInterruptNormal(V, hssRxBEyeQualityIntr_f, &pcie_normal, 1);
    cmd = DRV_IOW(PcieIntfInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &pcie_normal);

    /*mask IpeAclInterruptNormal.timestampOverrun*/
     cmd = DRV_IOR(IpeAclInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &ipe_acl_normal);
    SetIpeAclInterruptNormal(V, timestampOverrun_f, &ipe_acl_normal, 1);
    cmd = DRV_IOW(IpeAclInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, &ipe_acl_normal);

    sal_memset(value, 0, sizeof(value));
    SetSupIntrNormal(V, rlmMiscNormalIntr_f, &value, 1);
    cmd = DRV_IOW(SupIntrNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &value);

    cmd = DRV_IOR(SupIntrFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_SET, cmd, value);
    value[0] = value[0] & (~(1<<6));/* Tcam Scan Error*/
    cmd = DRV_IOW(SupIntrFunc_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, value);

    /* clear mask pfc normal interrupt*/
    step = QuadSgmacInterruptNormal0_intSgmac1RxPauseLockDetect_f - QuadSgmacInterruptNormal0_intSgmac0RxPauseLockDetect_f;
    for(i = 0; i <= 15; i++)
    {
        for(j = 0; j <= 3; j++)
        {
            SetQuadSgmacInterruptNormal0(V, intSgmac0RxPauseLockDetect_f+j*step, &quadsgmac_normal, 1);
        }
        cmd = DRV_IOW(QuadSgmacInterruptNormal0_t + i, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, INTR_INDEX_MASK_RESET, cmd, &quadsgmac_normal);
    }

    /*clear some interrupt */
    cmd = DRV_IOR(PcieIntfInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &value_set);
    cmd = DRV_IOW(PcieIntfInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 1, cmd, &value_set);

    cmd = DRV_IOR(PcieIntfInterruptFatal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &value_set);
    cmd = DRV_IOW(PcieIntfInterruptFatal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 1, cmd, &value_set);

    cmd = DRV_IOR(RlmHsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &hs_normal);
    cmd = DRV_IOW(RlmHsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 1, cmd, &hs_normal);

    cmd = DRV_IOR(RlmCsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &cs_normal);
    cmd = DRV_IOW(RlmCsCtlInterruptNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 1, cmd, &cs_normal);

    cmd = DRV_IOR(SupIntrNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_VAL_SET, cmd, &value);
    cmd = DRV_IOW(SupIntrNormal_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, INTR_INDEX_VAL_RESET, cmd, &value);

    return CTC_E_NONE;
}

int32
sys_tsingma_interrupt_set_sup_op(uint8 lchip, uint8 grp_id, uint8 act_idx)
{
    uint32 cmd = 0;
    SupIntrGenCtl_m sup_ctl;
    uint32 value = 0;

    value = (1 << grp_id);

    sal_memset(&sup_ctl, 0, sizeof(sup_ctl));
    if (INTR_INDEX_VAL_SET == act_idx)
    {
        SetSupIntrGenCtl(V, supIntrValueSet_f, &sup_ctl, value);
    }
    else if (INTR_INDEX_VAL_RESET == act_idx)
    {
        SetSupIntrGenCtl(V, supIntrValueClr_f, &sup_ctl, value);
    }
    else if (INTR_INDEX_MASK_SET == act_idx)
    {
        SetSupIntrGenCtl(V, supIntrMaskSet_f, &sup_ctl, value);
    }
    else
    {
        SetSupIntrGenCtl(V, supIntrMaskClr_f, &sup_ctl, value);

        /*When release msi interrup, clear Pcie0IntrLogCtl_pcie0IntrLogVec_f*/
        if (p_usw_intr_master[lchip]->intr_mode == CTC_INTR_MODE_MSI || p_usw_intr_master[lchip]->intr_mode == CTC_INTR_MODE_MSIX)
        {
            /*TM/TMM process*/
            cmd = DRV_IOR(PcieIntrLogCtl_t, PcieIntrLogCtl_pcieIntrLogVec_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            CTC_BIT_UNSET(value, grp_id);
            cmd = DRV_IOW(PcieIntrLogCtl_t, PcieIntrLogCtl_pcieIntrLogVec_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        }
    }

    cmd = DRV_IOW(SupIntrGenCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sup_ctl));
    return CTC_E_NONE;
}


